home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-28 | 7.9 KB | 406 lines | [TEXT/MPS ] |
- /*
- File: Queues.cp
-
- Copyright: © 1991-1994 by Apple Computer, Inc.
- All rights reserved.
-
- Part of the AOCE Sample SMSAM Package. Consult the license
- which came with this software for your specific legal rights.
-
- */
-
-
-
- #ifndef __QUEUES__
- #include "Queues.h"
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __DEBUGASSERT__
- #include "DebugAssert.h"
- #endif
-
- #ifndef __DEBUGGINGGEAR__
- #include "DebuggingGear.h"
- #endif
-
- /***********************************|****************************************/
-
- #pragma segment Queue
-
- /***********************************|****************************************/
-
- void* const kBadObject = (void*) 0xFFFFFFFF;
-
- extern void BreakStr ( const Str255 str );
-
- /***********************************|****************************************/
-
- class TQueueItem {
- public: TQueueItem ( void * object,
- TQueueItem * prev = nil,
- TQueueItem * next = nil );
- ~TQueueItem ( );
-
- void * GetObject ( ) const { return fItem; }
-
- TQueueItem * GetNextItem () const { return fNextItem; }
- TQueueItem * GetPrevItem () const { return fPrevItem; }
-
- void SetNextItem ( TQueueItem * next ) { fNextItem = next; }
- void SetPrevItem ( TQueueItem * prev ) { fPrevItem = prev; }
-
- protected:
- TQueueItem * fNextItem;
- TQueueItem * fPrevItem;
- void * fItem;
- };
-
- /***********************************|****************************************/
-
- TQueueItem::TQueueItem ( void * o, TQueueItem * prev, TQueueItem * next ) :
- fItem ( o ),
- fNextItem ( next ),
- fPrevItem ( prev )
- {
- if ( next )
- next->SetPrevItem ( this );
-
- if ( prev )
- prev->SetNextItem ( this );
- }
-
- /***********************************|****************************************/
-
- TQueueItem::~TQueueItem ( )
- {
- if ( fPrevItem )
- fPrevItem->SetNextItem ( fNextItem );
-
- if ( fNextItem )
- fNextItem->SetPrevItem ( fPrevItem );
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- TQueue::TQueue ( Boolean ownsObjects ):
- fFirst ( nil ),
- fLast ( nil ),
- fSpareQueueItems ( nil ),
- fCount ( 0 ),
- fOwnsObjects ( ownsObjects )
- {
- }
-
- /***********************************|****************************************/
-
- TQueue::~TQueue ()
- {
- if ( fCount > 0 && fOwnsObjects )
- DeleteAll ();
- }
-
- /***********************************|****************************************/
-
- void
- TQueue::SetOwnsObjects ( Boolean ownsObjects )
- {
- fOwnsObjects = ownsObjects;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TQueue::GetOwnsObjects () const
- {
- return fOwnsObjects;
- }
-
- /***********************************|****************************************/
-
- unsigned long
- TQueue::Find ( const void* object ) const
- {
- TQueueItem * queueItem = fFirst;
- unsigned long index = 1;
-
- while ( queueItem )
- if ( object == queueItem->GetObject() )
- return index;
- else
- {
- index ++;
- queueItem = queueItem->GetNextItem();
- }
-
- return 0;
- }
-
- /***********************************|****************************************/
-
-
- TQueueItem*
- TQueue::GetQueueItem ( unsigned long index ) const
- {
- TQueueItem * item = fFirst;
-
- if ( index <= fCount )
- {
- while ( item && ( index > 1 ) )
- {
- item = item->GetNextItem();
- index -- ;
- }
-
- return item;
- }
- else
- return nil;
- }
-
- /***********************************|****************************************/
-
- void*
- TQueue::Get ( unsigned long index ) const
- {
- TQueueItem * item = GetQueueItem ( index );
-
- if ( item )
- return item->GetObject();
-
- #if debug
- BreakStr ( "\pinvalid index" );
- #endif
- return nil;
-
- }
-
- /***********************************|****************************************/
-
- void*
- TQueue::operator [] ( unsigned long index ) const
- {
- TQueueItem * item = GetQueueItem ( index - 1 );
-
- if ( item )
- return item->GetObject();
-
- #if debug
- BreakStr ( "\pinvalid index" );
- #endif
- return nil;
- }
-
- /***********************************|****************************************/
-
- void TQueue::Append ( void * object )
- {
- // Insert as the last item in the queue.
- TQueueItem * newItem = new TQueueItem ( object, fLast, nil );
- fLast = newItem;
- if ( !fFirst )
- fFirst = newItem;
- fCount ++;
- }
-
- /***********************************|****************************************/
-
- void
- TQueue::Insert ( unsigned long index, void* object )
- {
- #if debug
- if ( index == 0 )
- {
- BreakStr ( "\pzero user index" );
- return;
- }
- #endif
-
- // Constrain 1 <= index <= fCount
- index = ( index < 1 ) ? 1 : ( index >= fCount ) ? fCount : index;
-
- if ( index > 1 )
- {
- if ( index < fCount )
- {
- TQueueItem * itemToInsert = GetQueueItem ( index );
- TQueueItem * newItem = new TQueueItem ( object, itemToInsert, itemToInsert->GetNextItem() );
- }
- else
- {
- // Insert as the last item in the queue.
- TQueueItem * newItem = new TQueueItem ( object, fLast, nil );
- fLast = newItem;
- }
- }
- else
- {
- {
- // Insert as the first item in the queue.
- TQueueItem * newItem = new TQueueItem ( object, nil, fFirst );
- fFirst = newItem;
-
- if ( !fLast )
- fLast = newItem;
- }
- }
-
- fCount++;
- }
-
- /***********************************|****************************************/
-
- void*
- TQueue::Remove ( unsigned long index )
- {
- #if debug
- if ( !IsValidIndex ( index ) )
- {
- // BreakStr ( "\pTQueue::Remove(), bad index" );
- return nil;
- }
- #endif
- TQueueItem * itemToRemove = GetQueueItem ( index );
-
- if ( itemToRemove )
- {
- if ( fFirst == itemToRemove )
- fFirst = itemToRemove->GetNextItem();
-
- if ( fLast == itemToRemove )
- fLast = itemToRemove->GetPrevItem();
-
- if ( itemToRemove->GetPrevItem() )
- itemToRemove->GetPrevItem()->SetNextItem ( itemToRemove->GetNextItem() );
-
- if ( itemToRemove->GetNextItem() )
- itemToRemove->GetNextItem()->SetPrevItem ( itemToRemove->GetPrevItem() );
-
- // Stick this item into the queue of 'spare' queue items;
- itemToRemove->SetNextItem ( fSpareQueueItems );
- fSpareQueueItems = itemToRemove;
-
- fCount --;
-
- return itemToRemove->GetObject();
- }
-
- return nil;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TQueue::Delete ( unsigned long index )
- {
- void* object = Remove ( index );
-
- if ( object )
- {
- DeleteObject ( object );
- return true;
- }
- else
- {
- return false;
- }
- }
-
- /***********************************|****************************************/
-
- Boolean
- TQueue::Remove ( const void* object )
- {
- unsigned long index = Find ( object );
-
- if ( index > 0 )
- {
- Remove ( index );
- return true;
- }
- else
- {
- return false;
- }
- }
-
- /***********************************|****************************************/
-
- void
- TQueue::RemoveAll ()
- {
- // Move all of the stuff from the queue into the fSpareQueueItems list.
-
- if ( fLast )
- {
- fLast->SetNextItem ( fSpareQueueItems );
- fSpareQueueItems = fFirst;
- }
-
- fFirst = fLast = nil;
- fCount = 0;
- }
-
- /***********************************|****************************************/
-
- Boolean
- TQueue::Delete ( void* object )
- {
- Boolean removed = Remove ( object );
-
- if ( removed )
- DeleteObject ( object );
-
- return removed;
- }
-
- /***********************************|****************************************/
-
- void
- TQueue::DeleteAll ()
- {
- TQueueItem * item = fFirst;
-
- while ( item )
- {
- DeleteObject ( item->GetObject() );
- item = item->GetNextItem();
- }
-
- fCount = 0;
- }
-
- /***********************************|****************************************/
-
- void
- TQueue::DeleteObject ( void* object ) const
- {
- delete object;
- }
-
- /***********************************|****************************************/
-
- ostream&
- TQueue::operator >> ( ostream& s ) const
- {
- // subclasses should stream their name, then call this method
-
- s << " @ " << (void*) this << ": (" << Count() << ") ";
-
- for ( unsigned long index = 0; index < fCount; index++ )
- {
- if ( index > 0 )
- s << ",";
-
- s << Get ( index + 1 );
- }
-
- return s;
- }
-
- /***********************************|****************************************/